\section{Dificuldades com a Linguagem}

\label{sec:dificuldades}

Para o nosso projeto, especialmente para a etapa de análise semântica, a
linguagem PHP apresentou muitas dificuldades, tanto por sua característica de
tipagem dinâmica -- como já discutido anteriormente -- quanto por sua extrema
flexibilidade (que possibilita a programação de códigos válidos bastante
obscuros) e por seu aspecto interpretado.

A flexibilidade provida pela linguagem por vezes possibilita a construção de
trechos de código obscuros, como vemos nos exemplos a seguir.

\begin{lstlisting}[frame=single,
caption={Chamada de função com mais parâmetros que o
definido},label=lst:exemploObscuro1, numbers=left, breaklines=true,
language=PHP, extendedchars=true, literate={á}{{\'a}}1 {ã}{{\~a}}1 {é}{{\'e}}1 {ç}{{\c{c}}}1 {Ç}{{\c{C}}}1 {ó}{{\'o}}1 {í}{{\'i}}1 {à}{{'a}}1 {õ}{{\~o}}1, showstringspaces=false, showspaces=false, morekeywords={}]
<?php 
function soma($a, $b) {
	return $a + $b;
}

echo soma(5, 5, 1); // Imprime o resultado 10, ignorando o parametro não usado
echo soma(5, 5, 1, 2, 3, 4, 5, 6, 7); // Imprime o resultado 10, ignorando os parametros não usados 
?>
\end{lstlisting}

No exemplo \ref{lst:exemploObscuro1}, foi definida uma função \texttt{soma}, que
recebe dois parâmetros e retorna sua soma. Quando é feita a chamada com mais do
que dois parâmetros, o interpretador não aponta erros, apenas utilizando os dois
primeiros e ignorando os demais. No exemplo \ref{lst:exemploObscuro2}, a função
é definida para receber um parâmetro, que não é usado em seu corpo. Devido à
interpretação de PHP, chamar a função sem passar parâmetro algum, não resulta
em erro, visto que o parâmetro não é usado no corpo da função.

\begin{lstlisting}[frame=single,
caption={Chamada de função sem passagem de parâmetro},label=lst:exemploObscuro2,
numbers=left, breaklines=true, language=PHP, extendedchars=true, literate={á}{{\'a}}1 {ã}{{\~a}}1 {é}{{\'e}}1 {ç}{{\c{c}}}1 {Ç}{{\c{C}}}1 {ó}{{\'o}}1 {í}{{\'i}}1 {à}{{'a}}1 {õ}{{\~o}}1, showstringspaces=false, showspaces=false, morekeywords={}]
<?php 
function a($x) {
	return 'ok';
}

echo a(1); // Imprime o retorno 'ok'
echo a(); // Imprime o mesmo retorno 'ok'  
?>
\end{lstlisting}

Esse tipo de possibilidade de PHP impossibilitou a checagem de parâmetros em
nossa análise semântica, uma vez que tudo é permitido. Caso o corpo da função
faça uso de alguma variável que não foi passada em sua chamada, será apontado
erro devido ao uso de uma variável não definida, como em qualquer outro tipo de
bloco. 

Outra dificuldade surgiu pela maneira dinâmica de PHP tratar suas expressões.
Qualquer expressão em PHP possui valor booleano, como mostramos na tabela
\ref{tbl:tabelaValores} para os diversos tipos.

\begin{table}
\begin{center}
	\begin{tabular}{| c | c |}
		\hline
		\textbf{Expressão} & \textbf{Valor booleano} \\
		
		\hline
		\verb#$x = "";# & \texttt{FALSE}\\
		
		\hline
		\verb#$x = NULL# & \texttt{FALSE}\\
		
		\hline
		\verb#var $x;# & \texttt{FALSE}\\
		
		\hline
		\verb#$x = array();# & \texttt{FALSE} \\
		
		\hline
		\verb#$x = false;# & \texttt{FALSE} \\
		
		\hline
		\verb#$x = 1;# & \texttt{TRUE} \\
		
		\hline
		\verb#$x = 42;# & \texttt{TRUE} \\

		\hline
		\verb#$x = 0;# & \texttt{FALSE} \\

		\hline
		\verb#$x = -1;# & \texttt{TRUE} \\
		
		\hline
		\verb#$x = "1";# & \texttt{TRUE} \\
		
		\hline
		\verb#$x = "0";# & \texttt{FALSE} \\
		
		\hline
		\verb#$x = "-1";# & \texttt{TRUE} \\
		
		\hline
		\verb#$x = "php";# & \texttt{TRUE} \\
		
		\hline
		\verb#$x = "true";# & \texttt{TRUE} \\
		
		\hline
		\verb#$x = "false";# & \texttt{TRUE} \\
		\hline
	\end{tabular}
\end{center}
\label{tbl:tabelaValores}
\caption{Avaliação de expressões em valores booleanos}
\end{table}

Dessa maneira, sempre que necessária uma expressão booleana, qualquer expressão
poderá ser usada, e avaliada de acordo com os valores da tabela
\ref{tbl:tabelaValores}.

\begin{lstlisting}[frame=single,
caption={Avaliação de expressões para valores
booleanos},label=lst:expressoesBooleanas, numbers=left, breaklines=true,
language=PHP, extendedchars=true, literate={á}{{\'a}}1 {ã}{{\~a}}1 {é}{{\'e}}1 {ç}{{\c{c}}}1 {Ç}{{\c{C}}}1 {ó}{{\'o}}1 {í}{{\'i}}1 {à}{{'a}}1 {õ}{{\~o}}1, showstringspaces=false, showspaces=false, morekeywords={}]
<?php 
if (0) {
	echo "Entrou no if";	// Não será impresso
}
else {
	echo "Entrou no else";	// Será impresso
}

if ("0") {
	echo "Entrou no if";	// Não será impresso
}
else {
	echo "Entrou no else";	// Será impresso
}

if ("compiladores") {
	echo "Entrou no if";	// Será impresso
}
else {
	echo "Entrou no else";	// Não será impresso
}
?>
\end{lstlisting}

No exemplo \ref{lst:expressoesBooleanas}, as expressões \verb#0# e \verb#"0"#
são avaliadas como \verb#FALSE#, fazendo com que o fluxo seja desviado como
mostrado nos comentários. Já a string \verb#"compiladores"# é avaliada como
\verb#TRUE# (todas as strings diferentes de \verb#"0"# são \verb#TRUE#).

O caráter interpretado de PHP também nos levou a maiores problemas nessa etapa
principalmente com o \emph{bind}. Através de muitas pesquisas e testes,
descobrimos que PHP só faz a declaração de funções em tempo de execução, como
mostrado no exemplo \ref{lst:exemploFuncaoExecucao}.

\begin{lstlisting}[frame=single,
caption={Declaração de função em tempo de
execução},label=lst:exemploFuncaoExecucao, numbers=left, breaklines=true,
language=PHP, extendedchars=true, literate={á}{{\'a}}1 {ã}{{\~a}}1 {é}{{\'e}}1 {ç}{{\c{c}}}1 {Ç}{{\c{C}}}1 {ó}{{\'o}}1 {í}{{\'i}}1 {à}{{'a}}1 {õ}{{\~o}}1, showstringspaces=false, showspaces=false, morekeywords={}] 
<?php 
if (true) {
	function a() {
		echo 'a';
	}
}
else {
	function b() {
		echo 'b';
	}
}
?>
\end{lstlisting}

No caso do exemplo \ref{lst:exemploFuncaoExecucao}, só teremos declarada a
função \verb#a()#, pois o fluxo de execução é desviado para esse ramo, e não
teremos declarada a função \verb#b()#, possibilitando a declaração de uma outra
função \verb#b()# (PHP não permite declaração de funções com o mesmo nome), além
de invocar um erro fatal caso seja chamada a função \verb#b()#.

Isso tornou inviável diversos tratamentos em nosso projeto, pois: as expressões
só podem ser avaliadas em tempo de execução; o escopo será alterado de acordo
com as funções, que são declaradas em tempo de execução; a árvore de derivação
só pode ser completamente construída durante a execução.

Dessa maneira, decidimos por fazer uma restrição na linguagem para podermos
melhorar os tratamentos da análise semântica, e ainda possibilitar a futura
geração de código pelo compilador, visto a impossibilidade de se ter a árvore de
derivação previamente à execução do código. Essa restrição que adotamos é
abordada na seção \ref{sec:}